<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, minimal-ui">
    <title>keyboard测试</title>
    <link rel="shortcut icon" href="../image/app_icon.png" type="image/png">
    <link rel="bookmark" href="../image/app_icon.png">

    <style>
      button {
        background-color: white;
        box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.2), 0 3px 5px 0 rgba(0, 0, 0, 0.19);
        border: 0;
        border-radius: 5px;
        cursor: pointer;
        text-align: center;
        font-family: "comic sans ms";
        font-size: 0.6rem;
        padding: 0;
        /*禁止长按选中文本,无效果*/
        user-select: none;
        -ms-user-select: none; /* IE 11 */
        -webkit-user-select: none; /* Chrome/Safari */
        -moz-user-select: none; /* Firefox */
      }

      button:active {
        box-shadow: 0 4px 8px 0 rgba(79, 239, 239, 61), 0 3px 10px 0 rgba(0, 255, 255, 61);
        border: 0;
      }

      .key-bg {
        background-color: #cccccc;
        padding: 2px 5px 5px 5px;
        width: 626px;
        border-radius: 10px;
      }

      .key-row {
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        margin: 3px 0 0 0;
      }

      .key-bg button {
        width: 38px;
        height: 38px;
      }

      /* btnWidth*(2/3)=*0.6 */
      .key-bg .btnWidth-x0d6 {
        width: 22px;
      }

      .key-bg .btnWidth-x1 {
        width: 38px;
      }

      .key-bg .btnWidth-x1d3 {
        width: 49px;
      }

      .key-bg .btnWidth-x1d5 {
        width: 57px;
      }

      .key-bg .btnWidth-x1d8 {
        width: 68px;
      }

      .key-bg .btnWidth-x2 {
        width: 76px;
      }

      .key-bg .btnWidth-x2d2 {
        width: 83px;
      }

      .key-bg .btnWidth-x2d6 {
        width: 99px;
      }

      .key-bg .btnWidth-x6d6 {
        width: 250px;
      }

      /*数字键盘*/
      .num-board {
        display: grid;
        grid-template-rows: repeat(5, 1fr);
        grid-template-columns: repeat(4, 1fr);
        grid-gap: 3px;
        margin-left: 3px;
        margin-top: 38px;
        width: 180px;
        height: 210px;
      }

      .num-board button {
        width: auto;
        height: auto;
      }

      .mediaButton {
        letter-spacing: -2px;
        font-size: 12px;
        font-weight: bold;
      }

      .lamp-board {
        background-color: #fff;
        box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.2), 0 3px 5px 0 rgba(0, 0, 0, 0.19);
        border-radius: 10px;
        font-size: 0.6rem;
        padding: 0 5px;
        white-space: nowrap;
      }

      .lamp-row {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        justify-items: center;
        height: 50%;
      }

      .lamp-on {
        color: #03a9f4;
      }

      .lamp-off {
        color: gray;
      }
    </style>
</head>
<body style="margin: 0; padding: 0;overflow: hidden;">
<!--
   键盘
   https://www.cnblogs.com/2979100039-qq-con/archive/2020/04/06/12641603.html
   keyCode java.awt.event.KeyEvent
   特殊字符
   https://www.cnblogs.com/gaozhang12345/p/17273657.html
-->
<div style="height: 100vh;  width: 100vw;">

    <div id="keyboard" style="height: 100vh; display: flex; justify-content: center; align-items: center;">
        <div id="main-board" class="key-bg">
            <div class="key-row">
                <span class="btnWidth-x1d3"></span>
                <button keyCode="" class="mediaButton">▶/║</button>
                <button keyCode="" class="mediaButton">┃◀◀</button>
                <button keyCode="" class="mediaButton">▶▶┃</button>
                <span class="btnWidth-x1d3"></span>
                <button>Home</button>
                <button>End</button>
                <button>Pg▲</button>
                <button>Pg▼</button>
                <span class="btnWidth-x0d6"></span>

                <div class="lamp-board btnWidth-x2d6">
                    <!--[其它方案时,不分两行]会导致[同行内容对不齐]-->
                    <div class="lamp-row" style="align-items: end">
                        <span class="lamp-on lamp-off1">◉</span>
                        <span class="lamp-on lamp-off">◉</span>
                        <span class="lamp-on lamp-off">◉</span>
                        <span class="lamp-on lamp-off">◉</span>
                    </div>
                    <div class="lamp-row" style="align-items: baseline">
                        <span>连接</span>
                        <span>①</span>
                        <span>Ⓐ</span>
                        <span>Ⓢ</span>
                    </div>
                </div>
                <span class="btnWidth-x0d6"></span>

                <button id="btnSetting" class="btnWidth-x1">设置</button>
                <button id="btnMode" class="btnWidth-x1">Mode</button>
            </div>
            <!---->
            <div class="key-row">
                <button keyCode="">Esc</button>
                <span class="btnWidth-x0d6"></span>
                <button keyCode="">F1</button>
                <button keyCode="">F2</button>
                <button keyCode="">F3</button>
                <button keyCode="">F4</button>
                <span class="btnWidth-x0d6"></span>
                <button keyCode="">F5</button>
                <button keyCode="">F6</button>
                <button keyCode="">F7</button>
                <button keyCode="">F8</button>
                <span class="btnWidth-x0d6"></span>
                <button keyCode="">F9</button>
                <button keyCode="">F10</button>
                <button keyCode="">F11</button>
                <button keyCode="">F12</button>
            </div>
            <!---->
            <div class="key-row">
                <button keyCode="">~<br/>丶</button>
                <button keyCode="">!<br/>1</button>
                <button keyCode="">@<br/>2</button>
                <button keyCode="">#<br/>3</button>
                <button keyCode="">$<br/>4</button>
                <button keyCode="">%<br/>5</button>
                <button keyCode="">^<br/>6</button>
                <button keyCode="">&<br/>7</button>
                <button keyCode="">*<br/>8</button>
                <button keyCode="">(<br/>9</button>
                <button keyCode="">)<br/>0</button>
                <button keyCode="">_<br/>-</button>
                <button keyCode="">+<br/>=</button>
                <button keyCode="" class="btnWidth-x1d5">⇍</button>
                <button>Del</button>
            </div>
            <!---->
            <div class="key-row">
                <button keyCode="" class="btnWidth-x1d5">Tab↹</button>
                <button keyCode="">Q</button>
                <button keyCode="">W</button>
                <button keyCode="">E</button>
                <button keyCode="">R</button>
                <button keyCode="">T</button>
                <button keyCode="">Y</button>
                <button keyCode="">U</button>
                <button keyCode="">I</button>
                <button keyCode="">O</button>
                <button keyCode="">P</button>
                <button keyCode="">{<br/>[</button>
                <button keyCode="">}<br/>]</button>
                <button keyCode="" class="btnWidth-x1d8">|<br/>\</button>
            </div>
            <!---->
            <div class="key-row">
                <button keyCode="" class="btnWidth-x1d8">CapsⒶ</button>
                <button keyCode="">A</button>
                <button keyCode="">S</button>
                <button keyCode="">D</button>
                <button keyCode="">F</button>
                <button keyCode="">G</button>
                <button keyCode="">H</button>
                <button keyCode="">J</button>
                <button keyCode="">K</button>
                <button keyCode="">L</button>
                <button keyCode="">:<br/>;</button>
                <button keyCode="">"<br/>'</button>
                <button keyCode="" class="btnWidth-x2d6">Enter⏎</button>
            </div>
            <!---->
            <div class="key-row">
                <button class="btnWidth-x2d2">Shift</button>
                <button>Z</button>
                <button>X</button>
                <button>C</button>
                <button>V</button>
                <button>B</button>
                <button>N</button>
                <button>M</button>
                <button><<br/>,</button>
                <button>><br/>.</button>
                <button>?<br/>/</button>

                <span class="btnWidth-x1"></span>
                <button keyCode="">↑</button>
                <span class="btnWidth-x1"></span>
            </div>
            <!---->
            <div class="key-row">
                <button class="btnWidth-x1d3">Ctrl</button>
                <button class="btnWidth-x1d3">Win</button>
                <button class="btnWidth-x1d3">Alt</button>
                <button class="btnWidth-x6d6">_____</button>
                <button class="btnWidth-x1d3">Menu</button>

                <span class="btnWidth-x1"></span>
                <button keyCode="">←</button>
                <button keyCode="">↓</button>
                <button keyCode="">→</button>
            </div>
        </div>

        <div class="num-board key-bg" style="display: none">
            <button keyCode="">Num</button>
            <button keyCode="">/</button>
            <button keyCode="">*</button>
            <button keyCode="">-</button>
            <!---->
            <button keyCode="" style="grid-row: 2/4; grid-column: 4;">+</button>
            <button keyCode="">7</button>
            <button keyCode="">8</button>
            <button keyCode="">9</button>
            <button keyCode="">4</button>
            <button keyCode="">5</button>
            <button keyCode="">6</button>
            <!---->
            <button keyCode="">1</button>
            <button keyCode="">2</button>
            <button keyCode="">3</button>
            <button keyCode="" style="grid-row: 4/6;grid-column: 4;">⏎</button>
            <!---->
            <button keyCode="" style="grid-column: 1/3">0</button>
            <button keyCode="">.</button>
        </div>
    </div>
</div>
<script>
  const browserUtil = {
    /**
     * @return {boolean} 是否已全屏
     */
    isFullScreen() {
      // console.log(document.fullscreenElement, document.mozFullScreenElement, document.webkitFullscreenElement, document.msFullscreenElement, screen.isFullscreen)
      return !!(document.fullscreenElement
        || document.mozFullScreenElement
        || document.webkitFullscreenElement
        || document.msFullscreenElement
        || screen.isFullscreen)
    },
    toFullScreen() {
      let documentElement = document.documentElement
      let fullMethod = documentElement.requestFullScreen  //W3C
        || documentElement.mozRequestFullScreen  //Firefox
        || documentElement.webkitRequestFullscreen //Chrome, Safari and Opera
        || documentElement.msRequestFullScreen //IE/Edge
      if (fullMethod) fullMethod.call(documentElement)
    },
    exitFullscreen() {
      let exitMethod = document.exitFullscreen  //W3C
        || document.mozCancelFullScreen  //Firefox
        || document.webkitExitFullscreen //Chrome, Safari and Opera
        || document.msExitFullscreen //IE/Edge
      if (exitMethod) exitMethod.call(document)
    },
    /**
     * 切换全屏
     * https://blog.csdn.net/qq_25285531/article/details/130356246
     */
    switchFullScreen() {
      if (!this.isFullScreen()) {
        this.toFullScreen()
      } else {
        this.exitFullscreen()
      }
    },
  }
</script>
<script type="module">
  function initKeyboard() {
    let realWid, realHei//整个键盘的尺寸,含右侧键盘
    if (window.innerWidth > window.innerHeight) {
      //横屏
      realWid = window.innerWidth
      realHei = window.innerHeight
    } else {
      //竖屏
      realWid = window.innerHeight
      realHei = window.innerWidth
    }
    // 要减去key-bg的padding, 因为element.style.width=Wid时, 组件实际尺寸是[Wid+两边padding]
    realWid -= 10
    // realHei -= 10 //不用减,因为不用setHeight,计算时要包含padding

    /*
    键盘尺寸和布局制定思路
    .固定好按钮布局(很关键)
    .注释js, 直接写死css: 按钮尺寸=38*38,按钮行距=3px, 按钮数量=[Tab所在的行]=15
    .键盘四条边的padding都是5px(其中top=bg的2px+row的3px)
    .mainBoard总宽度(不含左右padding)=按钮宽*数量+按钮左margin*(数量-1), css最佳效果=38*15+4*14
    .再微调每行的按钮宽度(处理某行的水平padding)

    实际尺寸计算
    .前面得到的css效果是固定尺寸下的, 动态计算时,要微调
    .总宽度=btnWidth*15+margin*14, 其中margin应转成[btnWidth*比例]
    .总高度(含上下padding)=btnWidth*7+margin*8
     */
    let mainBoardWidth = realWid
    if (mode !== 0) {
      //比例=(main按钮数量-padding差)/总按钮数量
      mainBoardWidth = Math.floor(mainBoardWidth * 14.9 / 19)
    }
    //计算按钮尺寸
    let columnCount = 15, rowCount = 7
    let btnWidth = Math.floor(mainBoardWidth * 12 / (13 * columnCount - 1))//采用 padding=w/12
    //高度不够时
    let maxBtnHeight = Math.floor(realHei * 12 / (13 * rowCount + 1))
    if (maxBtnHeight < btnWidth) {
      // noinspection JSSuspiciousNameCombination
      btnWidth = maxBtnHeight
      mainBoardWidth = Math.floor(btnWidth * (13 * columnCount - 1) / 12)
    }
    let fontSize = btnWidth / 38 * 0.6
    let lineHeight = fontSize > 0.5 ? '' : '12px'
    console.log(`[${window.innerWidth}x${window.innerHeight}], btnWidth=${btnWidth}, mainBoardWidth=${mainBoardWidth}, fontSize=${fontSize}`)

    //keyboard 自适应横竖屏旋转
    let keyboard = document.getElementById('keyboard')
    if (window.innerWidth > window.innerHeight) {
      keyboard.style.transform = ``
    } else {
      keyboard.style.transform = `rotate(270deg)`
    }

    // mainBoard宽度
    let mainBoard = document.getElementById('main-board')
    mainBoard.style.width = `${mainBoardWidth}px`
    //此处关键!! 解决[竖屏时,键盘旋转后,指定了mainBoard.width],但mainBoard.实际width无效的诡异情况
    mainBoard.style.minWidth = `${mainBoardWidth}px`

    //mainBoard按钮尺寸
    for (let button of mainBoard.getElementsByTagName('button')) {
      button.style.fontSize = `${fontSize}rem`
      button.style.width = `${btnWidth}px`
      button.style.height = `${btnWidth}px`
      button.style.lineHeight = lineHeight
    }

    //查找样式'btnWidth-x' 并计算实际width值, 刷新dom
    let rules = document.styleSheets[0].cssRules || document.styleSheets[0].rules
    for (let i = 0; i < rules.length; i++) {
      const rule = rules[i];
      if (!rule.selectorText.includes('btnWidth-x')) continue

      let text = rule.selectorText
      text = text.substring(text.indexOf('btnWidth-x'))
      let ratio = parseFloat(text.substring(text.indexOf('-x') + 2).replace('d', '.'))
      let targetWidth = Math.floor(btnWidth * ratio)
      // console.log(`style=${text}, ratio=${ratio}, targetWidth=${targetWidth}, `)

      for (let element of document.getElementsByClassName(text)) {
        element.style.width = `${targetWidth}px`
      }
    }

    //指示灯
    let lamp = document.getElementsByClassName('lamp-board')[0]
    lamp.style.height = `${btnWidth}px`
    lamp.style.fontSize = `${fontSize}rem`
    lamp.style.lineHeight = lineHeight

    //右侧组件
    let numBoard = document.getElementsByClassName('num-board')[0]
    if (mode === 0) {
      numBoard.style.display = 'none'
    } else if (mode === 1) {
      //数字键盘
      numBoard.style.display = 'grid'
      numBoard.style.marginTop = `0px`
      numBoard.style.width = `auto`
      numBoard.style.height = `auto`

      for (let button of numBoard.getElementsByTagName('button')) {
        button.style.fontSize = `${fontSize}rem`
        if (!button.style.gridColumn) {
          button.style.width = `${btnWidth}px`
          button.style.height = `${btnWidth}px`
        } else {
          button.style.width = `auto`
          button.style.height = `auto`
        }
      }
    }
  }

  let mode = JSON.parse(window.localStorage.getItem('keyboardMode-t') || '0')
  document.getElementsByClassName('num-board')[0].style.display = mode ? 'grid' : 'none'

  {
    initKeyboard()
    window.onresize = () => initKeyboard()
    document.getElementById('btnSetting').addEventListener('click', () => browserUtil.switchFullScreen())
    document.getElementsByClassName('lamp-board')[0].addEventListener('click', () => location.reload())
    document.getElementById('btnMode').addEventListener('click', () => {
      mode = (mode + 1) % 2;
      window.localStorage.setItem('keyboardMode-t', mode)
      console.log(`mode=${mode}`)
      initKeyboard()
    })
  }
</script>
</body>
</html>